﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace dasBlog.Storage
{
    public static class StorageNodeFactory
    {
        public static IStorageNode CreateStorageNode<T>()
        {
            return CreateStorageNode(typeof(T));
        }

        public static IStorageNode CreateStorageNode<T>(string providerInitData)
        {
            return CreateStorageNode(typeof(T), providerInitData);
        }

        public static IStorageNode CreateStorageNode(Type providerType)
        {
            return CreateStorageNode(providerType, null);
        }

        public static IStorageNode CreateStorageNode(Type providerType, string providerInitData)
        {
            object provider = CreateProvider(providerType, providerInitData);
            if (provider is IStreamStorageProvider)
            {
                return new StreamStorageNodeService((IStreamStorageProvider)provider) as IStorageNode;
            }
            else
            {
                return WrapProvider(provider);
            }
        }

        private static object CreateProvider(Type providerType, string providerInitData)
        {
            object provider = Activator.CreateInstance(providerType);
            if (provider is IInitStorageProvider && providerInitData != null)
            {
                ((IInitStorageProvider)provider).Initialize(providerInitData);
            }
            return provider;
        }

        private static IStorageNode WrapProvider(object provider)
        {
            Type itemType = null;
            foreach (Type itf in provider.GetType().GetInterfaces())
            {
                if (itf.IsGenericType &&
                     itf.GetGenericTypeDefinition() == typeof(IStorageProvider<>))
                {
                    itemType = itf.GetGenericArguments()[0];
                }
            }
            if (itemType == null)
            {
                return null;
            }
            else
            {
                Type stgNodeType = typeof(StorageNodeService<>).MakeGenericType(itemType);
                return Activator.CreateInstance(stgNodeType, provider) as IStorageNode;
            }
        }
    }
}
